import { jsx as _jsx } from "react/jsx-runtime";
import React from "react";
import classNames from "classnames";
import CustomStore from "devextreme/data/custom_store";
import DataSource from "devextreme/data/data_source";
import { formatPrice } from "../../../tools/Tools";
import ReactDOM from "react-dom/client";
import { Workbook } from "exceljs";
import { saveAs } from "file-saver";
import { exportDataGrid } from "devextreme/excel_exporter";
import { message } from "antd";
import ReactDOMRender from "react-dom";
import { LogicPopup } from "../../../components-bs/LogicPopup/index";
import { exportDataToExcel } from "./exportExcelService";
/**
 * 默认开启
 * 1. 开启dev组件默认行为
 * 1.1 列移动
 * 1.2 拖拽调整列宽
 *  1.3 根据文本内容调整列宽
 * 1.4 用户自定义Fix
 * 1.5 列隐藏
 * 1.6 全局过滤，字段过滤
 * 1.7 filter panel 自定义搜索条件 ， 可以指定列逻辑组合过滤
 *  'string' | 'number' | 'date' | 'boolean' | 'object' | 'datetime'
 * @param WrappedComponent
 * @constructor
 */
export default function DevGridDefaultHoc(WrappedComponent) {
    // 泛型限定
    return class extends WrappedComponent {
        parent = super.render();
        dataSource;
        defaultConfig = {
            allowColumnReordering: true,
            allowColumnResizing: true,
            filterRow: {
                visible: false,
                applyFilter: "auto",
            },
            height: "100%",
            searchPanel: {
                visible: false,
                width: 240,
                placeholder: "搜索",
            },
            headerFilter: {
                visible: true,
                texts: {
                    ok: "确定",
                },
            },
            filterPanel: {
                visible: false,
            },
            columnChooser: {
                enabled: false,
            },
            grouping: {
                contextMenuEnabled: true,
                expandMode: "rowClick",
            },
            // 显示斑马线
            rowAlternationEnabled: true,
            // groupPanel: {
            //   visible: true,
            // },
        };
        contentRef;
        gridRef;
        draftPopupRef;
        pageSize = 10;
        currentIsGroup = false;
        currentGroupField = "";
        logicPopupDom = document.createElement("div");
        getGridInstance() {
            try {
                return this.gridRef.current.instance;
            }
            catch (error) {
                console.log("@@@ this.gridRef.current", error);
            }
        }
        //兼容devExpress写法
        get instance() {
            return this.gridRef.current.instance;
        }
        isShowFilter = false;
        isFilterNullData = false;
        constructor(...props) {
            super(...props);
            this.gridRef = React.createRef();
            this.contentRef = React.createRef();
            this.draftPopupRef = React.createRef();
            this.state = {
                dataSource: this.props.dataSource,
            };
            const p = props[0];
            const store = new CustomStore({
                key: p.keyExpr,
                load: (loadOptions) => {
                    //TODO 远端分页
                    // if (p.isRemote) {
                    //   return [];
                    // }
                    return p.dataSource;
                },
            });
            this.logicPopupDom = document.createElement("div");
            this.dataSource = new DataSource({
                pageSize: this.pageSize,
                store: store,
                // paginate: true,
            });
            this.onDataExporting = this.onDataExporting.bind(this);
            this.exportName = this.exportName.bind(this);
            this.searchByTextGridData = this.searchByTextGridData.bind(this);
            this.gridContentReady = this.gridContentReady.bind(this);
            this.handleSort = this.handleSort.bind(this);
            this.onCellClickMethod = this.onCellClickMethod.bind(this);
            this.onExportDraft = this.onExportDraft.bind(this);
        }
        exportName() {
            const { excelName } = this.props;
            const tempImgName = `${new Date().getFullYear()}${new Date().getMonth() + 1}${new Date().getDate() >= 10
                ? new Date().getDate()
                : "0" + new Date().getDate()}${new Date().getMilliseconds()}${Math.floor(Math.random() * 1000000 + 1)}.xlsx`;
            return excelName ? `${excelName}.xlsx` : tempImgName;
        }
        searchByTextGridData(value) {
            // const grid = this.gridRef.current.instance;
            // const { defaultColumns } = this.gridRef.current.props;
            // const filterData = defaultColumns.map((el) => {
            //   return [el.dataField, "contains", value];
            // });
            // console.log(filterData);
            // if (value && grid) {
            //   //  "=", "<>", "<", ">", "<=", ">=", "between", "contains", "notcontains", "startswith", "endswith", "anyof", "noneof",
            //   // grid.filter(filterData);
            //   // const sss = grid.getCombinedFilter("CompanyName");
            //   // console.log(sss);
            //   // grid.filter(["CompanyName", "contains", value]);
            //  } else {
            //   grid.clearFilter();
            // }
            if (this.getGridInstance()) {
                const grid = this.getGridInstance();
                grid.searchByText(value);
            }
        }
        /**
         * todo 取消devExpress内置的导出方式，用 xlsx-js-style 自己拼装。
         */
        onDataExporting(eExport, isSelect) {
            const { sheetName } = this.props;
            const workbook = new Workbook();
            const worksheet = workbook.addWorksheet(sheetName);
            exportDataGrid({
                component: eExport,
                worksheet,
                autoFilterEnabled: true,
                selectedRowsOnly: isSelect,
                customizeCell({ excelCell, gridCell }) {
                    const borderStyle = { style: "thin", color: { argb: "000000" } };
                    const cellVal = excelCell.value;
                    excelCell.font = {
                        size: 12,
                        name: cellVal && typeof cellVal === "number"
                            ? "Arial narrow"
                            : "华文中宋",
                    };
                    excelCell.border = {
                        bottom: borderStyle,
                        left: borderStyle,
                        right: borderStyle,
                        top: borderStyle,
                    };
                    excelCell.numFmt = "#,##0.00";
                    if (+excelCell.value === 0) {
                        excelCell.value = null;
                    }
                },
            }).then(async () => {
                await workbook.xlsx.writeBuffer().then((buffer) => {
                    saveAs(new Blob([buffer], { type: "application/octet-stream " }), this.exportName());
                });
                window["$desktop"] &&
                    window["$desktop"].invoke({
                        channel: "toggleOverlay",
                        data: {
                            visible: false, // 是否显示
                        },
                    });
            });
        }
        async generateExcel({ selectFilePath, eExport, isSelect, draftSheetName, }) {
            const workbook = new Workbook();
            const worksheet = workbook.addWorksheet("new sheet");
            console.log(selectFilePath, "selectFilePath");
            return await exportDataGrid({
                component: eExport,
                worksheet,
                autoFilterEnabled: true,
                selectedRowsOnly: isSelect,
                customizeCell({ excelCell }) {
                    const borderStyle = { style: "thin", color: { argb: "000000" } };
                    const cellVal = excelCell.value;
                    excelCell.font = {
                        size: 12,
                        name: cellVal && typeof cellVal === "number"
                            ? "Arial narrow"
                            : "华文中宋",
                    };
                    excelCell.numFmt = "#,##0.00";
                    excelCell.border = {
                        bottom: borderStyle,
                        left: borderStyle,
                        right: borderStyle,
                        top: borderStyle,
                    };
                    if (+excelCell.value === 0) {
                        excelCell.value = null;
                    }
                },
            }).then(async () => {
                return workbook.xlsx.writeBuffer().then(async (buffer) => {
                    try {
                        //const { code } = await window.parent[
                        const { code } = await window["businessService"].excelManageGetExcelData({
                            type: "devExpress",
                            filePath: selectFilePath,
                            sheetData: buffer,
                            sheetName: draftSheetName,
                            mergedCells: [],
                            autoFilter: {
                                ...worksheet.autoFilter,
                            },
                        });
                        if (+code === 200) {
                            message.success("导出成功");
                        }
                        else {
                            message.error("导出失败，请重试");
                        }
                    }
                    catch (err) {
                        message.success("导出失败，请重试");
                        throw err;
                    }
                });
            });
        }
        async onExportDraft(eExport, isSelect) {
            const { draftSheetName = "new sheet" } = this.props;
            return this.draftPopupRef.current.show({
                title: "导出到底稿",
                okCallback: async (r, v) => {
                    // 获取选中的数据
                    console.log(draftSheetName);
                    return this.generateExcel({
                        selectFilePath: r,
                        eExport,
                        isSelect,
                        draftSheetName: draftSheetName,
                    });
                },
            });
        }
        componentDidMount() {
            ReactDOMRender.render(_jsx(LogicPopup, { ref: this.draftPopupRef }), this.logicPopupDom);
            document.body.appendChild(this.logicPopupDom);
        }
        componentDidUpdate() {
            if (this.isFilterNullData) {
                this.emptyDataVisible();
            }
            this.setState({
                dataSource: this.props.dataSource,
            });
        }
        componentWillUnmount() {
            document.body.removeChild(this.logicPopupDom);
            console.log("卸载事件");
            console.log("卸载dataSource");
            this.dataSource.dispose();
            this.getGridInstance().dispose();
        }
        //自定义sort
        hocColumns(defaultColumns) {
            for (let i = 0; i < defaultColumns?.length; i++) {
                const columnItem = defaultColumns[i];
                // 自定义头部渲染模板
                columnItem.headerCellTemplate = (container, e) => {
                    const div = document.createElement("div");
                    if (e.column.index === 0 && !this.props.disableFirstHeaderSearch) {
                        const i = document.createElement("i");
                        i.className = `iconfont icon-search grid-search`;
                        i.id = "grid-search";
                        div.appendChild(i);
                    }
                    div.innerHTML += columnItem.caption;
                    container.appendChild(div);
                };
                if (columnItem.cellRender) {
                    columnItem.cellTemplate = (container, options) => {
                        const reactNode = columnItem.cellRender(options);
                        const root = ReactDOM.createRoot(container);
                        root.render(reactNode);
                    };
                }
                if (columnItem.dataTypeCustom === "zh-string") {
                    columnItem.sortingMethod = function (value1, value2) {
                        // Handling null values
                        if (!value1 && value2)
                            return -1;
                        if (!value1 && !value2)
                            return 0;
                        if (value1 && !value2)
                            return 1;
                        // Determines whether two strings are equivalent in the current locale
                        return value1.localeCompare(value2, "zh-Hans-CN", {
                            sensitivity: "accent",
                        });
                    };
                }
                if (columnItem.dataTypeCustom === "money-number") {
                    columnItem.alignment = "right";
                    columnItem.format = function (value) {
                        if (value === 0 || value === "0") {
                            return " ";
                        }
                        return formatPrice(value);
                    };
                }
                if (columnItem.columns) {
                    this.hocColumns(columnItem.columns);
                }
            }
        }
        gridContentReady(e) {
            console.log("表格加载");
        }
        sortAsc(dataField) {
            this.getGridInstance().clearSorting();
            this.getGridInstance().columnOption(dataField, {
                sortOrder: "asc",
            });
        }
        sortDesc(dataField) {
            this.getGridInstance().columnOption(dataField, {
                sortOrder: "desc",
            });
        }
        //空数据不展示
        emptyDataVisible() {
            const dataSource = this.getGridInstance().getDataSource();
            const columns = this.getGridInstance().getVisibleColumns();
            dataSource.filter((itemData) => {
                let numberCount = 0;
                let numberCountVar = 0;
                for (let i = 0; i < columns.length; i++) {
                    const column = columns[i];
                    if (column.dataType === "number") {
                        ++numberCount;
                    }
                }
                for (let i = 0; i < columns.length; i++) {
                    const column = columns[i];
                    if (column.dataType === "number") {
                        const val = itemData[column.dataField];
                        if (val === 0 || val === "" || val === null || val === undefined) {
                            ++numberCountVar;
                        }
                    }
                }
                if (this.isFilterNullData) {
                    if (numberCount === 0) {
                        return true;
                    }
                    else {
                        return numberCount !== numberCountVar;
                    }
                }
                else {
                    return true;
                }
            });
            dataSource.load();
        }
        handleSort() {
            this.defaultConfig.filterPanel.visible = !this.isShowFilter;
            this.defaultConfig.filterRow.visible = !this.isShowFilter;
            this.getGridInstance().clearFilter();
            this.getGridInstance().option("filterRow.visible", !this.isShowFilter);
            this.getGridInstance().option("filterPanel.visible", !this.isShowFilter);
            this.isShowFilter = !this.isShowFilter;
            this.emptyDataVisible();
        }
        ContextMenu(e) {
            const { column, row, columnIndex, rowIndex } = e;
            const { isRemote } = this.props;
            let dataField;
            if (column)
                dataField = column.dataField;
            let propsMenus = [];
            if (super.ContextMenu) {
                propsMenus = super.ContextMenu(e);
            }
            const grid = this.getGridInstance();
            const _this = this;
            let defaultMenu = [
                {
                    text: "排序",
                    items: [
                        {
                            text: "升序排序",
                            onItemClick: () => {
                                this.sortAsc(dataField);
                            },
                        },
                        {
                            text: "降序排序",
                            onItemClick: () => {
                                this.sortDesc(dataField);
                            },
                        },
                        {
                            text: "取消排序",
                            onItemClick: () => {
                                this.getGridInstance().clearSorting();
                            },
                        },
                    ],
                    relyTable: true,
                },
                //731临时隐藏
                // 隐藏分组
                // {
                //   text: "分组",
                //   items: [
                //     {
                //       text: "加入分组",
                //       onItemClick: () => {
                //         if (this.currentGroupField) {
                //           this.getGridInstance().columnOption(this.currentGroupField, {
                //             groupIndex: undefined,
                //           });
                //         }
                //         this.getGridInstance().columnOption(dataField, {
                //           groupIndex: 0,
                //         });
                //         this.currentIsGroup = true;
                //         this.currentGroupField = dataField;
                //       },
                //     },
                //     {
                //       text: "取消分组",
                //       onItemClick: () => {
                //         this.getGridInstance().columnOption(this.currentGroupField, {
                //           groupIndex: undefined,
                //         });
                //       },
                //     },
                //     // {
                //     //   text: "升序排序",
                //     //   onItemClick: () => {
                //     //     if (this.currentGroupField) {
                //     //       this.sortAsc(this.currentGroupField);
                //     //     }
                //     //   },
                //     // },
                //     // {
                //     //   text: "降序排序",
                //     //   onItemClick: () => {
                //     //     if (this.currentGroupField) {
                //     //       this.sortDesc(this.currentGroupField);
                //     //     }
                //     //   },
                //     // },
                //     // {
                //     //   text: "取消排序",
                //     //   onItemClick: () => {
                //     //     this.getGridInstance().clearSorting();
                //     //   },
                //     // },
                //     // {
                //     //   text: "展开所有",
                //     //   onItemClick: () => {
                //     //     this.getGridInstance().expandAll(0);
                //     //   },
                //     // },
                //     // {
                //     //   text: "收起所有",
                //     //   onItemClick: () => {
                //     //     this.getGridInstance().collapseAll(0);
                //     //   },
                //     // },
                //   ],
                //   relyTable: true,
                // },
                {
                    text: `${this.isShowFilter ? "隐藏过滤条" : "显示过滤条"}`,
                    onItemClick: _this.handleSort,
                    remoteDisabled: true, //远程获取数据需要隐藏掉
                },
                {
                    text: "选择可见列",
                    onItemClick: () => {
                        this.getGridInstance().showColumnChooser();
                    },
                },
                {
                    text: `${this.isFilterNullData ? "空数据显示" : "空数据不显示"}`,
                    onItemClick: () => {
                        this.emptyDataVisible();
                        this.isFilterNullData = !this.isFilterNullData;
                    },
                    remoteDisabled: true,
                    relyTable: true,
                },
                // {
                //   text: "删除此行",
                //   onItemClick: () => {
                //     const dataSource = [...this.state.dataSource];
                //     const key =
                //       typeof row.key === "number" ? row.key - 1 : row.dataIndex;
                //     dataSource.splice(key, 1);
                //     this.setState({
                //       dataSource,
                //     });
                //   },
                //   relyTable: true,
                // },
                {
                    text: "导出Excel",
                    items: [
                        {
                            text: "导出全部Excel",
                            onItemClick: async (e) => {
                                const { loadAllDevGridExport, defaultColumns, columns } = this.props;
                                window["$desktop"] &&
                                    window["$desktop"].invoke({
                                        channel: "toggleOverlay",
                                        data: {
                                            visible: true,
                                            timeout: 600000, // 超时时间，默认5000ms
                                        },
                                    });
                                if (loadAllDevGridExport) {
                                    try {
                                        const excelColumns = defaultColumns
                                            ? defaultColumns
                                            : columns;
                                        const { dataSource } = await loadAllDevGridExport();
                                        await exportDataToExcel(excelColumns, dataSource, this.exportName()); //执行导出全部Excel
                                        window["$desktop"] &&
                                            window["$desktop"].invoke({
                                                channel: "toggleOverlay",
                                                data: {
                                                    visible: false, // 是否显示
                                                },
                                            });
                                    }
                                    catch (e) {
                                        throw e;
                                    }
                                }
                                else {
                                    this.onDataExporting(grid, false);
                                }
                            },
                        },
                    ],
                },
                //  731 临时隐藏
                // {
                //   text: "导出底稿平台",
                //   items: [
                //     {
                //       text: "导出底稿平台",
                //       onItemClick: (e) => {
                //         this.onExportDraft(grid, false);
                //       },
                //     },
                //   ],
                // },
            ];
            if (isRemote) {
                defaultMenu = defaultMenu.filter((item) => !item.remoteDisabled);
            }
            // treeList树形表格先禁用导出
            if (grid && grid.NAME === "dxTreeList") {
                //defaultMenu.splice(5, 2);
                //0825临时隐藏树形表格组件右键导出功能
                defaultMenu = defaultMenu.filter((item) => item.text !== "导出Excel");
            }
            console.log(defaultMenu);
            const _defaultMenu = column
                ? defaultMenu
                : defaultMenu.filter((item) => !item.relyTable);
            console.log([..._defaultMenu, ...propsMenus], "dev grid");
            return [..._defaultMenu, ...propsMenus];
        }
        toolBar(e) {
            let dataGrid = e.component;
            e.toolbarOptions.items.unshift({
                location: "after",
                widget: "dxCheckBox",
                options: {
                    text: "过滤条是否显示",
                    value: this.defaultConfig.filterRow.visible,
                    onValueChanged: (e) => {
                        // 当调用表格的 option时要把以前的对象引用重置， 因为每次option 会拿原始对象进行重新渲染.
                        this.defaultConfig.filterRow.visible = e.value;
                        dataGrid.clearFilter();
                        dataGrid.option("filterRow.visible", e.value);
                    },
                },
            }, {
                location: "after",
                widget: "dxCheckBox",
                options: {
                    text: "无数据不显示",
                    onValueChanged: (e) => {
                        const value = e.value;
                        this.dataSource.filter((itemData) => {
                            const columns = this.parent.props["defaultColumns"];
                            let numberCount = 0;
                            let numberCountVar = 0;
                            for (let i = 0; i < columns.length; i++) {
                                const column = columns[i];
                                if (column.dataType === "number") {
                                    ++numberCount;
                                }
                            }
                            for (let i = 0; i < columns.length; i++) {
                                const column = columns[i];
                                if (column.dataType === "number") {
                                    const val = itemData[column.dataField];
                                    if (val === 0 || val === "") {
                                        ++numberCountVar;
                                    }
                                }
                            }
                            if (value) {
                                return numberCount !== numberCountVar;
                            }
                            else {
                                return true;
                            }
                        });
                        this.dataSource.load();
                    },
                },
            }, {
                location: "after",
                widget: "dxButton",
                options: {
                    icon: "refresh",
                    onClick: function () {
                        dataGrid.refresh();
                    },
                },
            });
        }
        onCellClickMethod(e) {
            if (e.rowType !== "header")
                return;
            if (e.event.target.id === "grid-search") {
                const sortOrder = e.column.sortOrder === "asc" ? "desc" : "asc";
                this.getGridInstance().columnOption(0, "sortOrder", sortOrder);
                this.handleSort();
            }
        }
        render() {
            const klass = classNames("cpas-grid", "devHeadersCenter PaperDevSortableGrid");
            const { defaultColumns, columns, ...rest } = this.props;
            //注入column逻辑
            this.hocColumns(Array.isArray(defaultColumns) && defaultColumns?.length > 0
                ? defaultColumns
                : columns);
            const defaultConfig = this.defaultConfig;
            let props = {
                className: klass,
                columnMinWidth: 70,
                columnResizingMode: "widget",
                columns: Array.isArray(defaultColumns) && defaultColumns?.length > 0
                    ? defaultColumns
                    : columns,
                ...defaultConfig,
                ...rest,
                onContextMenuPreparing: (e) => {
                    const contentMenu = this.ContextMenu(e);
                    if (e.target === "content") {
                        // e.items can be undefined
                        if (!e.items)
                            e.items = [];
                        // Add a custom menu item
                        e.items = contentMenu;
                    }
                },
                onContentReady: (e) => {
                    this.gridContentReady(e);
                    this.props.onContentReady && this.props.onContentReady(e);
                },
                onCellClick: this.onCellClickMethod,
                allowSearch: true,
                // onToolbarPreparing: this.toolBar,
                dataSource: this.state.dataSource,
                ref: this.gridRef,
            };
            return React.cloneElement(this.parent, {
                ...props,
                headerFilter: { ...props?.headerFilter, texts: { ok: "确定" } },
            });
        }
    };
}
